<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Create a Model and Database Table - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/learning.quickstart.create-model.html">Inglês (English)</a></li>
    <li><a href="../pt-br/learning.quickstart.create-model.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.quickstart.create-layout.html">Create A Layout</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.quickstart.html">Zend Framework Quick Start</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.quickstart.create-form.html">Create A Form</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="learning.quickstart.create-model" class="section"><div class="info"><h1 class="title">Create a Model and Database Table</h1></div>
    

    <p class="para">
        Before we get started, let&#039;s consider something: where will these classes live, and how will
        we find them? The default project we created instantiates an autoloader. We can attach other
        autoloaders to it so that it knows where to find different classes. Typically, we want our
        various MVC classes grouped under the same tree -- in this case,
        <var class="filename">application/</var> -- and most often using a common prefix.
    </p>

    <p class="para">
        <span class="classname">Zend_Controller_Front</span> has a notion of &quot;modules&quot;, which are individual
        mini-applications. Modules mimic the directory structure that the <strong class="command">zf</strong>
        tool sets up under <var class="filename">application/</var>, and all classes inside them are
        assumed to begin with a common prefix, the module name. <var class="filename">application/</var>
        is itself a module -- the &quot;default&quot; or &quot;application&quot; module. As such, we&#039;ll want to setup
        autoloading for resources within this directory.
    </p>

    <p class="para">
        <span class="classname">Zend_Application_Module_Autoloader</span> provides the functionality needed
        to map the various resources under a module to the appropriate directories, and provides a
        standard naming mechanism as well. An instance of the class is created by default during
        initialization of the bootstrap object; your application bootstrap will by default use the
        module prefix &quot;Application&quot;. As such, our models, forms, and table classes will all begin
        with the class prefix &quot;Application_&quot;.
    </p>

   <p class="para">
        Now, let&#039;s consider what makes up a guestbook. Typically, they are simply a list of entries
        with a <em class="emphasis">comment</em>, <em class="emphasis">timestamp</em>, and, often,
        <em class="emphasis">email address</em>. Assuming we store them in a database, we may also want a
        <em class="emphasis">unique identifier</em> for each entry. We&#039;ll likely want to be able to save
        an entry, fetch individual entries, and retrieve all entries. As such, a simple guestbook
        model <acronym class="acronym">API</acronym> might look something like this:
    </p>

    <pre class="programlisting brush: php">
// application/models/Guestbook.php

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __set($name, $value);
    public function __get($name);

    public function setComment($text);
    public function getComment();

    public function setEmail($email);
    public function getEmail();

    public function setCreated($ts);
    public function getCreated();

    public function setId($id);
    public function getId();
}

class Application_Model_GuestbookMapper
{
    public function save(Application_Model_Guestbook $guestbook);
    public function find($id);
    public function fetchAll();
}
</pre>


    <p class="para">
         <span class="methodname">__get()</span> and  <span class="methodname">__set()</span> will provide a
        convenience mechanism for us to access the individual entry properties, and proxy to the
        other getters and setters. They also will help ensure that only properties we whitelist will
        be available in the object.
    </p>

    <p class="para">
         <span class="methodname">find()</span> and  <span class="methodname">fetchAll()</span> provide the ability
        to fetch a single entry or all entries, while  <span class="methodname">save()</span> takes care of
        saving an entry to the data store.
    </p>

    <p class="para">
        Now from here, we can start thinking about setting up our database.
    </p>

    <p class="para">
        First we need to initialize our <span class="classname">Db</span> resource. As with the
        <span class="classname">Layout</span> and <span class="classname">View</span> resource, we can provide
        configuration for the <span class="classname">Db</span> resource. We can do this with the
        <strong class="command">zf configure db-adapter</strong> command:
    </p>

    <pre class="programlisting brush: shell">
% zf configure db-adapter \
&gt; &#039;adapter=PDO_SQLITE&amp;dbname=APPLICATION_PATH &quot;/../data/db/guestbook.db&quot;&#039; \
&gt; production
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
&gt; &#039;adapter=PDO_SQLITE&amp;dbname=APPLICATION_PATH &quot;/../data/db/guestbook-testing.db&quot;&#039; \
&gt; testing
A db configuration for the production has been written to the application config file.

% zf configure db-adapter \
&gt; &#039;adapter=PDO_SQLITE&amp;dbname=APPLICATION_PATH &quot;/../data/db/guestbook-dev.db&quot;&#039; \
&gt; development
A db configuration for the production has been written to the application config file.
</pre>


    <p class="para">
        Now edit your <var class="filename">application/configs/application.ini</var> file, where you&#039;ll
        see the following lines were added in the appropriate sections.
    </p>

    <pre class="programlisting brush: ini">
; application/configs/application.ini

[production]
; ...
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook.db&quot;

[testing : production]
; ...
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook-testing.db&quot;

[development : production]
; ...
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook-dev.db&quot;
</pre>


    <p class="para">
        Your final configuration file should look like the following:
    </p>

    <pre class="programlisting brush: ini">
; application/configs/application.ini

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
bootstrap.path = APPLICATION_PATH &quot;/Bootstrap.php&quot;
bootstrap.class = &quot;Bootstrap&quot;
appnamespace = &quot;Application&quot;
resources.frontController.controllerDirectory = APPLICATION_PATH &quot;/controllers&quot;
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH &quot;/layouts/scripts&quot;
resources.view[] =
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook.db&quot;

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook-testing.db&quot;

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = &quot;PDO_SQLITE&quot;
resources.db.params.dbname = APPLICATION_PATH &quot;/../data/db/guestbook-dev.db&quot;
</pre>


    <p class="para">
        Note that the database(s) will be stored in <var class="filename">data/db/</var>. Create those
        directories, and make them world-writeable. On unix-like systems, you can do that as
        follows:
    </p>

    <pre class="programlisting brush: shell">
% mkdir -p data/db; chmod -R a+rwX data
</pre>


    <p class="para">
        On Windows, you will need to create the directories in Explorer and set the permissions to
        allow anyone to write to the directory.
    </p>

    <p class="para">
        At this point we have a connection to a database; in our case, its a connection to a Sqlite
        database located inside our <var class="filename">application/data/</var> directory. So, let&#039;s
        design a simple table that will hold our guestbook entries.
    </p>

    <pre class="programlisting brush: sql">
-- scripts/schema.sqlite.sql
--
-- You will need load your database schema with this SQL.

CREATE TABLE guestbook (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    email VARCHAR(32) NOT NULL DEFAULT &#039;noemail@test.com&#039;,
    comment TEXT NULL,
    created DATETIME NOT NULL
);

CREATE INDEX &quot;id&quot; ON &quot;guestbook&quot; (&quot;id&quot;);
</pre>


    <p class="para">
        And, so that we can have some working data out of the box, lets create a few rows of
        information to make our application interesting.
    </p>

    <pre class="programlisting brush: sql">
-- scripts/data.sqlite.sql
--
-- You can begin populating the database with the following SQL statements.

INSERT INTO guestbook (email, comment, created) VALUES
    (&#039;ralph.schindler@zend.com&#039;,
    &#039;Hello! Hope you enjoy this sample zf application!&#039;,
    DATETIME(&#039;NOW&#039;));
INSERT INTO guestbook (email, comment, created) VALUES
    (&#039;foo@bar.com&#039;,
    &#039;Baz baz baz, baz baz Baz baz baz - baz baz baz.&#039;,
    DATETIME(&#039;NOW&#039;));
</pre>


    <p class="para">
        Now that we have both the schema and some data defined. Lets get a script together that we
        can now execute to build this database. Naturally, this is not needed in production, but
        this script will help developers build out the database requirements locally so they can
        have the fully working application. Create the script as
        <var class="filename">scripts/load.sqlite.php</var> with the following contents:
    </p>

    <pre class="programlisting brush: php">
// scripts/load.sqlite.php

/**
 * Script for creating and loading database
 */

// Initialize the application path and autoloading
defined(&#039;APPLICATION_PATH&#039;)
    || define(&#039;APPLICATION_PATH&#039;, realpath(dirname(__FILE__) . &#039;/../application&#039;));
set_include_path(implode(PATH_SEPARATOR, array(
    APPLICATION_PATH . &#039;/../library&#039;,
    get_include_path(),
)));
require_once &#039;Zend/Loader/Autoloader.php&#039;;
Zend_Loader_Autoloader::getInstance();

// Define some CLI options
$getopt = new Zend_Console_Getopt(array(
    &#039;withdata|w&#039; =&gt; &#039;Load database with sample data&#039;,
    &#039;env|e-s&#039;    =&gt; &#039;Application environment for which to create database (defaults to development)&#039;,
    &#039;help|h&#039;     =&gt; &#039;Help -- usage message&#039;,
));
try {
    $getopt-&gt;parse();
} catch (Zend_Console_Getopt_Exception $e) {
    // Bad options passed: report usage
    echo $e-&gt;getUsageMessage();
    return false;
}

// If help requested, report usage message
if ($getopt-&gt;getOption(&#039;h&#039;)) {
    echo $getopt-&gt;getUsageMessage();
    return true;
}

// Initialize values based on presence or absence of CLI options
$withData = $getopt-&gt;getOption(&#039;w&#039;);
$env      = $getopt-&gt;getOption(&#039;e&#039;);
defined(&#039;APPLICATION_ENV&#039;)
    || define(&#039;APPLICATION_ENV&#039;, (null === $env) ? &#039;development&#039; : $env);

// Initialize Zend_Application
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . &#039;/configs/application.ini&#039;
);

// Initialize and retrieve DB resource
$bootstrap = $application-&gt;getBootstrap();
$bootstrap-&gt;bootstrap(&#039;db&#039;);
$dbAdapter = $bootstrap-&gt;getResource(&#039;db&#039;);

// let the user know whats going on (we are actually creating a
// database here)
if (&#039;testing&#039; != APPLICATION_ENV) {
    echo &#039;Writing Database Guestbook in (control-c to cancel): &#039; . PHP_EOL;
    for ($x = 5; $x &gt; 0; $x--) {
        echo $x . &quot;\r&quot;; sleep(1);
    }
}

// Check to see if we have a database file already
$options = $bootstrap-&gt;getOption(&#039;resources&#039;);
$dbFile  = $options[&#039;db&#039;][&#039;params&#039;][&#039;dbname&#039;];
if (file_exists($dbFile)) {
    unlink($dbFile);
}

// this block executes the actual statements that were loaded from
// the schema file.
try {
    $schemaSql = file_get_contents(dirname(__FILE__) . &#039;/schema.sqlite.sql&#039;);
    // use the connection directly to load sql in batches
    $dbAdapter-&gt;getConnection()-&gt;exec($schemaSql);
    chmod($dbFile, 0666);

    if (&#039;testing&#039; != APPLICATION_ENV) {
        echo PHP_EOL;
        echo &#039;Database Created&#039;;
        echo PHP_EOL;
    }

    if ($withData) {
        $dataSql = file_get_contents(dirname(__FILE__) . &#039;/data.sqlite.sql&#039;);
        // use the connection directly to load sql in batches
        $dbAdapter-&gt;getConnection()-&gt;exec($dataSql);
        if (&#039;testing&#039; != APPLICATION_ENV) {
            echo &#039;Data Loaded.&#039;;
            echo PHP_EOL;
        }
    }

} catch (Exception $e) {
    echo &#039;AN ERROR HAS OCCURED:&#039; . PHP_EOL;
    echo $e-&gt;getMessage() . PHP_EOL;
    return false;
}

// generally speaking, this script will be run from the command line
return true;
</pre>


    <p class="para">
        Now, let&#039;s execute this script. From a terminal or the DOS command line, do the following:
    </p>

    <pre class="programlisting brush: shell">
% php scripts/load.sqlite.php --withdata
</pre>


    <p class="para">
        You should see output like the following:
    </p>

    <pre class="programlisting brush: text">
path/to/ZendFrameworkQuickstart/scripts$ php load.sqlite.php --withdata
Writing Database Guestbook in (control-c to cancel):
1
Database Created
Data Loaded.
</pre>


    <p class="para">
        Now we have a fully working database and table for our guestbook application. Our next few
        steps are to build out our application code. This includes building a data source (in our
        case, we will use <span class="classname">Zend_Db_Table</span>), and a data mapper to connect that
        data source to our domain model. Finally we&#039;ll also create the controller that will interact
        with this model to both display existing entries and process new entries.
    </p>

    <p class="para">
        We&#039;ll use a <a href="http://martinfowler.com/eaaCatalog/tableDataGateway.html" class="link external">&raquo; Table Data
            Gateway</a> to connect to our data source; <span class="classname">Zend_Db_Table</span>
        provides this functionality. To get started, lets create a
        <span class="classname">Zend_Db_Table</span>-based table class. Just as we&#039;ve done for layouts and
        the database adapter, we can use the <strong class="command">zf</strong> tool to assist, using the command
        <strong class="command">create db-table</strong>. This takes minimally two arguments, the name by which
        you want to refer to the class, and the database table it maps to.
    </p>

    <pre class="programlisting brush: shell">
% zf create db-table Guestbook guestbook
Creating a DbTable at application/models/DbTable/Guestbook.php
Updating project profile &#039;zfproject.xml&#039;
</pre>


    <p class="para">
        Looking at your directory tree, you&#039;ll now see that a new directory,
        <var class="filename">application/models/DbTable/</var>, was created, with the file
        <var class="filename">Guestbook.php</var>. If you open that file, you&#039;ll see the following
        contents:
    </p>

    <pre class="programlisting brush: php">
// application/models/DbTable/Guestbook.php

/**
 * This is the DbTable class for the guestbook table.
 */
class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
{
    /** Table name */
    protected $_name    = &#039;guestbook&#039;;
}
</pre>


    <p class="para">
        Note the class prefix: <span class="classname">Application_Model_DbTable</span>. The class prefix
        for our module, &quot;Application&quot;, is the first segment, and then we have the component,
        &quot;Model_DbTable&quot;; the latter is mapped to the <var class="filename">models/DbTable/</var> directory
        of the module.
    </p>

    <p class="para">
        All that is truly necessary when extending <span class="classname">Zend_Db_Table</span> is to
        provide a table name and optionally the primary key (if it is not &quot;id&quot;).
    </p>

    <p class="para">
        Now let&#039;s create a <a href="http://martinfowler.com/eaaCatalog/dataMapper.html" class="link external">&raquo; Data
            Mapper</a>. A <em class="emphasis">Data Mapper</em> maps a domain object to the database.
        In our case, it will map our model, <span class="classname">Application_Model_Guestbook</span>, to
        our data source, <span class="classname">Application_Model_DbTable_Guestbook</span>. A typical
        <acronym class="acronym">API</acronym> for a data mapper is as follows:
    </p>

    <pre class="programlisting brush: php">
// application/models/GuestbookMapper.php

class Application_Model_GuestbookMapper
{
    public function save($model);
    public function find($id, $model);
    public function fetchAll();
}
</pre>


    <p class="para">
        In addition to these methods, we&#039;ll add methods for setting and retrieving the Table Data
        Gateway. To create the initial class, use the <strong class="command">zf</strong> CLI tool:
    </p>

    <pre class="programlisting brush: shell">
% zf create model GuestbookMapper
Creating a model at application/models/GuestbookMapper.php
Updating project profile &#039;.zfproject.xml&#039;
</pre>


    <p class="para">
        Now, edit the class <span class="classname">Application_Model_GuestbookMapper</span> found in
        <var class="filename">application/models/GuestbookMapper.php</var> to read as follows:
    </p>

    <pre class="programlisting brush: php">
// application/models/GuestbookMapper.php

class Application_Model_GuestbookMapper
{
    protected $_dbTable;

    public function setDbTable($dbTable)
    {
        if (is_string($dbTable)) {
            $dbTable = new $dbTable();
        }
        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception(&#039;Invalid table data gateway provided&#039;);
        }
        $this-&gt;_dbTable = $dbTable;
        return $this;
    }

    public function getDbTable()
    {
        if (null === $this-&gt;_dbTable) {
            $this-&gt;setDbTable(&#039;Application_Model_DbTable_Guestbook&#039;);
        }
        return $this-&gt;_dbTable;
    }

    public function save(Application_Model_Guestbook $guestbook)
    {
        $data = array(
            &#039;email&#039;   =&gt; $guestbook-&gt;getEmail(),
            &#039;comment&#039; =&gt; $guestbook-&gt;getComment(),
            &#039;created&#039; =&gt; date(&#039;Y-m-d H:i:s&#039;),
        );

        if (null === ($id = $guestbook-&gt;getId())) {
            unset($data[&#039;id&#039;]);
            $this-&gt;getDbTable()-&gt;insert($data);
        } else {
            $this-&gt;getDbTable()-&gt;update($data, array(&#039;id = ?&#039; =&gt; $id));
        }
    }

    public function find($id, Application_Model_Guestbook $guestbook)
    {
        $result = $this-&gt;getDbTable()-&gt;find($id);
        if (0 == count($result)) {
            return;
        }
        $row = $result-&gt;current();
        $guestbook-&gt;setId($row-&gt;id)
                  -&gt;setEmail($row-&gt;email)
                  -&gt;setComment($row-&gt;comment)
                  -&gt;setCreated($row-&gt;created);
    }

    public function fetchAll()
    {
        $resultSet = $this-&gt;getDbTable()-&gt;fetchAll();
        $entries   = array();
        foreach ($resultSet as $row) {
            $entry = new Application_Model_Guestbook();
            $entry-&gt;setId($row-&gt;id)
                  -&gt;setEmail($row-&gt;email)
                  -&gt;setComment($row-&gt;comment)
                  -&gt;setCreated($row-&gt;created);
            $entries[] = $entry;
        }
        return $entries;
    }
}
</pre>


    <p class="para">
        Now it&#039;s time to create our model class. We&#039;ll do so, once again, using the
        <strong class="command">zf create model</strong> command:
    </p>

    <pre class="programlisting brush: shell">
% zf create model Guestbook
Creating a model at application/models/Guestbook.php
Updating project profile &#039;.zfproject.xml&#039;
</pre>


    <p class="para">
        We&#039;ll modify this empty <acronym class="acronym">PHP</acronym> class to make it easy to populate the model
        by passing an array of data either to the constructor or a
         <span class="methodname">setOptions()</span> method. The final model class, located in
        <var class="filename">application/models/Guestbook.php</var>, should look like this:
    </p>

    <pre class="programlisting brush: php">
// application/models/Guestbook.php

class Application_Model_Guestbook
{
    protected $_comment;
    protected $_created;
    protected $_email;
    protected $_id;

    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this-&gt;setOptions($options);
        }
    }

    public function __set($name, $value)
    {
        $method = &#039;set&#039; . $name;
        if ((&#039;mapper&#039; == $name) || !method_exists($this, $method)) {
            throw new Exception(&#039;Invalid guestbook property&#039;);
        }
        $this-&gt;$method($value);
    }

    public function __get($name)
    {
        $method = &#039;get&#039; . $name;
        if ((&#039;mapper&#039; == $name) || !method_exists($this, $method)) {
            throw new Exception(&#039;Invalid guestbook property&#039;);
        }
        return $this-&gt;$method();
    }

    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key =&gt; $value) {
            $method = &#039;set&#039; . ucfirst($key);
            if (in_array($method, $methods)) {
                $this-&gt;$method($value);
            }
        }
        return $this;
    }

    public function setComment($text)
    {
        $this-&gt;_comment = (string) $text;
        return $this;
    }

    public function getComment()
    {
        return $this-&gt;_comment;
    }

    public function setEmail($email)
    {
        $this-&gt;_email = (string) $email;
        return $this;
    }

    public function getEmail()
    {
        return $this-&gt;_email;
    }

    public function setCreated($ts)
    {
        $this-&gt;_created = $ts;
        return $this;
    }

    public function getCreated()
    {
        return $this-&gt;_created;
    }

    public function setId($id)
    {
        $this-&gt;_id = (int) $id;
        return $this;
    }

    public function getId()
    {
        return $this-&gt;_id;
    }
}
</pre>


    <p class="para">
        Lastly, to connect these elements all together, lets create a guestbook controller that will
        both list the entries that are currently inside the database.
    </p>

    <p class="para">
        To create a new controller, use the <strong class="command">zf create controller</strong> command:
    </p>

    <pre class="programlisting brush: shell">
% zf create controller Guestbook
Creating a controller at
    application/controllers/GuestbookController.php
Creating an index action method in controller Guestbook
Creating a view script for the index action method at
    application/views/scripts/guestbook/index.phtml
Creating a controller test file at
    tests/application/controllers/GuestbookControllerTest.php
Updating project profile &#039;.zfproject.xml&#039;
</pre>


    <p class="para">
        This will create a new controller, <span class="classname">GuestbookController</span>, in
        <var class="filename">application/controllers/GuestbookController.php</var>, with a single action
        method,  <span class="methodname">indexAction()</span>. It will also create a view script directory
        for the controller, <var class="filename">application/views/scripts/guestbook/</var>, with a view
        script for the index action.
    </p>

    <p class="para">
        We&#039;ll use the &quot;index&quot; action as a landing page to view all guestbook entries.
    </p>

    <p class="para">
        Now, let&#039;s flesh out the basic application logic. On a hit to
         <span class="methodname">indexAction()</span>, we&#039;ll display all guestbook entries. This would look
        like the following:
    </p>

    <pre class="programlisting brush: php">
// application/controllers/GuestbookController.php

class GuestbookController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $guestbook = new Application_Model_GuestbookMapper();
        $this-&gt;view-&gt;entries = $guestbook-&gt;fetchAll();
    }
}
</pre>


    <p class="para">
        And, of course, we need a view script to go along with that. Edit
        <var class="filename">application/views/scripts/guestbook/index.phtml</var> to read as follows:
    </p>

    <pre class="programlisting brush: php">
&lt;!-- application/views/scripts/guestbook/index.phtml --&gt;

&lt;p&gt;&lt;a href=&quot;&lt;?php echo $this-&gt;url(
    array(
        &#039;controller&#039; =&gt; &#039;guestbook&#039;,
        &#039;action&#039;     =&gt; &#039;sign&#039;
    ),
    &#039;default&#039;,
    true) ?&gt;&quot;&gt;Sign Our Guestbook&lt;/a&gt;&lt;/p&gt;

Guestbook Entries: &lt;br /&gt;
&lt;dl&gt;
    &lt;?php foreach ($this-&gt;entries as $entry): ?&gt;
    &lt;dt&gt;&lt;?php echo $this-&gt;escape($entry-&gt;email) ?&gt;&lt;/dt&gt;
    &lt;dd&gt;&lt;?php echo $this-&gt;escape($entry-&gt;comment) ?&gt;&lt;/dd&gt;
    &lt;?php endforeach ?&gt;
&lt;/dl&gt;
</pre>


    <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>Checkpoint</b><br /></span>
        

        <p class="para">
            Now browse to &quot;http://localhost/guestbook&quot;. You should see the following in your
            browser:
        </p>

        <p class="para">
            <div class="inlinemediaobject"><div class="imageobject"><a href="images/d481d625821a97b9a5eb2cec99dca50e-learning.quickstart.create-model.png"><img src="images/d481d625821a97b9a5eb2cec99dca50e-learning.quickstart.create-model.png" alt="learning.quickstart.create-model.png" width="450" height="201" /></a></div></div>
        </p>
    </p></blockquote>

    <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>Using the data loader script</b><br /></span>
        

        <p class="para">
            The data loader script introduced in this section
            (<var class="filename">scripts/load.sqlite.php</var>) can be used to create the database for
            each environment you have defined, as well as to load it with sample data. Internally,
            it utilizes <span class="classname">Zend_Console_Getopt</span>, which allows it to provide a
            number of command line switches. If you pass the &quot;-h&quot; or &quot;--help&quot; switch, it will give
            you the available options:
        </p>

        <pre class="programlisting brush: php">
Usage: load.sqlite.php [ options ]
--withdata|-w         Load database with sample data
--env|-e [  ]         Application environment for which to create database
                      (defaults to development)
--help|-h             Help -- usage message)]]
</pre>


        <p class="para">
            The &quot;-e&quot; switch allows you to specify the value to use for the constant
            <b><tt>APPLICATION_ENV</tt></b> -- which in turn allows you to create a SQLite
            database for each environment you define. Be sure to run the script for the environment
            you choose for your application when deploying.
        </p>
    </p></blockquote>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="learning.quickstart.create-layout.html">Create A Layout</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="learning.quickstart.html">Zend Framework Quick Start</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="learning.quickstart.create-form.html">Create A Form</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="learning.html">Learning Zend Framework</a></li>
  <li class="header up"><a href="learning.quickstart.html">Zend Framework Quick Start</a></li>
  <li><a href="learning.quickstart.intro.html">Zend Framework &amp; MVC Introduction</a></li>
  <li><a href="learning.quickstart.create-project.html">Create Your Project</a></li>
  <li><a href="learning.quickstart.create-layout.html">Create A Layout</a></li>
  <li class="active"><a href="learning.quickstart.create-model.html">Create a Model and Database Table</a></li>
  <li><a href="learning.quickstart.create-form.html">Create A Form</a></li>
  <li><a href="learning.quickstart.conclusion.html">Congratulations!</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>